package com.own.component.common.handler;

import com.own.component.common.model.R;
import com.own.component.common.model.ResultModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.core.annotation.Order;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ValidatedExceptionHandler
 *
 * @author chenxueli
 * @date 2021/5/20 16:21
 */
@Slf4j
@Order(1)
@RestControllerAdvice
public class ValidatedExceptionHandler {

    /**
     * 处理@Validated参数校验失败异常
     *
     * @param e 异常类
     * @return 响应
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultModel<List<String>> handleException1(MethodArgumentNotValidException e) {
        var result = e.getBindingResult();
        return handle(result);
    }

    /**
     * 处理 spring-boot-starter-validation @Validated参数校验失败异常
     *
     * @param e 异常类
     * @return 响应
     */
    @ExceptionHandler(BindException.class)
    public ResultModel<List<String>> handleException2(BindException e) {
        var result = e.getBindingResult();
        return handle(result);
    }

    /**
     * 处理异常
     *
     * @param result 结果
     * @return 异常信息响应
     */
    private ResultModel<List<String>> handle(BindingResult result) {
        var messageList = result.hasErrors()
                ? result.getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.toList())
                : new ArrayList<String>();
        var model = R.success(messageList);
        model.setMessage(StringUtils.join(messageList, ","));
        model.setCode("00003");
        return model;
    }


}
